package com.mifengkong.frwidget.update.download;


import android.text.TextUtils;
import android.util.Log;

import com.mifengkong.frtools.util.FRLog;

import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.util.concurrent.TimeUnit;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;

/**
 * Created by Wang on 17/9/13
 */

public class BaseDownLoadManager extends BaseParameter {

    private OkHttpClient mClient;
    private Call mCall;
    private DownloadFailListener mDownloadFailListener;
    public BaseDownLoadManager() {
        if (mClient == null) {
            mClient = getProgressClient();
        }
    }

    public void setDownloadFailListener(DownloadFailListener mDownloadFailListener) {
        this.mDownloadFailListener = mDownloadFailListener;
    }

    private Call newCall(String url) {
        Request request = new Request.Builder()
                .url(url)
                .build();
        return mClient.newCall(request);
    }

    private OkHttpClient getProgressClient() {
        return new OkHttpClient.Builder()
                .addNetworkInterceptor(interceptor)
                .retryOnConnectionFailure(retryOnConnectionFailure)
                .connectTimeout(connectTimeout, TimeUnit.SECONDS)
                .writeTimeout(writeTimeout, TimeUnit.SECONDS)
                .readTimeout(readTimeout, TimeUnit.SECONDS)
                .build();
    }

    public void download(String url) {
        if (TextUtils.isEmpty(url)) {
            if(null != mDownloadFailListener){
                mDownloadFailListener.downloadFail(new Exception("下载链接为空!"));
            }
            return;
        }
        if (mSaveFile == null) {
            if(null != mDownloadFailListener){
                mDownloadFailListener.downloadFail(new Exception("保存APK的文件夹不存在!"));
            }
            return;
        }
        setUrl(url);
        mCall = newCall(url);
        mCall.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                if(null != mDownloadFailListener){
                    mDownloadFailListener.downloadFail(e);
                }

            }

            @Override
            public void onResponse(Call call, Response response) {
                save(response);
            }
        });
        startDownLoad();
    }

    protected void startDownLoad(){

    }

    protected void cancel(){
        if(null != mCall && !mCall.isCanceled()){
            Log.e("WANG","BaseDownLoadManager.cancel." );
            mCall.cancel();
        }
    }

    private void save(Response response) {
        ResponseBody body = response.body();
        InputStream in = body.byteStream();
        FileChannel channelOut = null;
        // 可以指定断点续传的起始位置
        RandomAccessFile randomAccessFile = null;
        try {
            randomAccessFile = new RandomAccessFile(mSaveFile, "rwd");
            //内存映射文件。
            channelOut = randomAccessFile.getChannel();
            // 内存映射，直接使用RandomAccessFile，是用其seek方法指定下载的起始位置，使用缓存下载，在这里指定下载位置。
            MappedByteBuffer mappedBuffer = channelOut.map(FileChannel.MapMode.READ_WRITE, 0, body.contentLength());
            byte[] buffer = new byte[1024];
            int len;
            while ((len = in.read(buffer)) != -1) {
                mappedBuffer.put(buffer, 0, len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                in.close();
                if (channelOut != null) {
                    channelOut.close();
                }
                if (randomAccessFile != null) {
                    randomAccessFile.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
